package cn.ctyun.videoplayer.player;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.AssetFileDescriptor;
import android.graphics.Color;
import android.media.AudioManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.OrientationEventListener;
import android.widget.FrameLayout;

import cn.ctyun.videoplayer.bean.MarqueeTextDetail;
import cn.ctyun.videoplayer.bean.VideoModel;
import cn.ctyun.videoplayer.bean.WaterMarkTextDetail;
import cn.ctyun.videoplayer.controller.BaseVideoController;
import cn.ctyun.videoplayer.controller.BaseMediaPlayerControlInterface;
import cn.ctyun.videoplayer.controller.StandardVideoController;
import cn.ctyun.videoplayer.listener.MarqueeViewListener;
import cn.ctyun.videoplayer.listener.OnEnterFullScreenListener;
import cn.ctyun.videoplayer.listener.OnErrorListener;
import cn.ctyun.videoplayer.listener.OnExitFullScreenListener;
import cn.ctyun.videoplayer.listener.OnLoadStartListener;
import cn.ctyun.videoplayer.listener.OnMuteListener;
import cn.ctyun.videoplayer.listener.OnPauseAdClickListener;
import cn.ctyun.videoplayer.listener.OnPauseListener;
import cn.ctyun.videoplayer.listener.OnPlayListener;
import cn.ctyun.videoplayer.listener.OnProgressChangeListener;
import cn.ctyun.videoplayer.listener.OnResumeVolumeListener;
import cn.ctyun.videoplayer.listener.OnSeekToListener;
import cn.ctyun.videoplayer.listener.OnSetVolumeListener;
import cn.ctyun.videoplayer.listener.OnStopListener;
import cn.ctyun.videoplayer.listener.OnVideoViewStateChangeListener;
import cn.ctyun.videoplayer.listener.PlayerEventListener;
import cn.ctyun.videoplayer.util.PlayerConstants;
import cn.ctyun.videoplayer.util.PlayerUtils;
import cn.ctyun.videoplayer.util.ProgressUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import cn.ctyun.videoplayer.playerevent.PlayerEventManager;
import cn.ctyun.videoplayer.util.SDKLog;
import tv.danmaku.ijk.media.player.IMediaPlayer;
import tv.danmaku.ijk.media.player.IjkMediaPlayer;

/**
 * 播放器
 * Created by Devlin_n on 2017/4/7.
 */

public abstract class BaseIjkVideoView extends FrameLayout implements BaseMediaPlayerControlInterface, PlayerEventListener {
    protected static final String TAG = BaseIjkVideoView.class.getSimpleName();
    protected List<VideoModel> mVideos;//列表播放数据
    protected WaterMarkTextDetail mWatermark;
    protected MarqueeTextDetail mMarqueeText;

    // 关联的Activity
    protected AppCompatActivity mAttachActivity;
    protected AbstractPlayer mMediaPlayer;//播放器
    @Nullable
    protected BaseVideoController mVideoController;//控制器
    protected boolean mIsMute;//是否静音

    protected String mCurrentUrl;//当前播放视频的地址
    protected String mCurrentVideoType;//当前播放视频的地址
    protected Map<String, String> mHeaders;//当前视频地址的请求头
    protected AssetFileDescriptor mAssetFileDescriptor;//assets文件
    protected long mCurrentPosition;//当前正在播放视频的位置
    protected String mCurrentTitle = "";//当前正在播放视频的标题

    //播放器的各种状态
    public static final int STATE_ERROR = -1;
    public static final int STATE_IDLE = 0;
    public static final int STATE_PREPARING = 1;
    public static final int STATE_PREPARED = 2;
    public static final int STATE_PLAYING = 3;
    public static final int STATE_PAUSED = 4;
    public static final int STATE_PLAYBACK_COMPLETED = 5;
    public static final int STATE_BUFFERING = 6;
    public static final int STATE_BUFFERED = 7;
    public static final int STATE_DLNA_CONNECTED = 8;
    protected int mCurrentPlayState = STATE_IDLE;//当前播放器的状态

    public static final int PLAYER_NORMAL = 10;        // 普通播放器
    public static final int PLAYER_FULL_SCREEN = 11;   // 全屏播放器
    protected int mCurrentPlayerState = PLAYER_NORMAL; // 播放器横屏/竖屏状态

    protected AudioManager mAudioManager;//系统音频管理器
    @Nullable
    protected AudioFocusHelper mAudioFocusHelper;

    protected int mCurrentOrientation = 0;
    protected static final int PORTRAIT = 1;
    protected static final int LANDSCAPE = 2;
    protected static final int REVERSE_LANDSCAPE = 3;

    protected boolean mIsLockFullScreen;//是否锁定屏幕
    protected PlayerConfig mPlayerConfig;//播放器配置

    public static boolean IS_PLAY_ON_MOBILE_NETWORK = false;//记录是否在移动网络下播放视频

    protected List<OnVideoViewStateChangeListener> mOnVideoViewStateChangeListeners;

    protected String mPauseAdUrl;
    // 开始播放前的海报
    protected String mThumbUrl;
    // 视频允许播放的时长，单位为秒
    protected long mPlayableVideoDuration;

    private boolean mEnableRecordPlayerEvent; // 是否记录播放器事件
    private boolean mFullScreenPortrait = false; // 是否全屏竖屏

    /**
     * 加速度传感器监听
     */
    protected OrientationEventListener mOrientationEventListener = new OrientationEventListener(getContext()) { // 加速度传感器监听，用于自动旋转屏幕
        private long mLastTime;

        @Override
        public void onOrientationChanged(int orientation) {
            long currentTime = System.currentTimeMillis();
            if (currentTime - mLastTime < 300) return;//300毫秒检测一次
            if (mVideoController == null) return;
            Activity activity = PlayerUtils.scanForActivity(mVideoController.getContext());
            if (activity == null) return;
            if (orientation >= 340) { //屏幕顶部朝上
                onOrientationPortrait(activity);
            } else if (orientation >= 260 && orientation <= 280) { //屏幕左边朝上
                onOrientationLandscape(activity);
            } else if (orientation >= 70 && orientation <= 90) { //屏幕右边朝上
                onOrientationReverseLandscape(activity);
            }
            mLastTime = currentTime;
        }
    };

    /**
     * 竖屏
     */
    protected void onOrientationPortrait(Activity activity) {
        if (mIsLockFullScreen || !mPlayerConfig.mAutoRotate || mCurrentOrientation == PORTRAIT)
            return;
        if ((mCurrentOrientation == LANDSCAPE || mCurrentOrientation == REVERSE_LANDSCAPE) && !isFullScreen()) {
            mCurrentOrientation = PORTRAIT;
            return;
        }
        mCurrentOrientation = PORTRAIT;
        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        stopFullScreen();
    }

    /**
     * 横屏
     */
    protected void onOrientationLandscape(Activity activity) {
        if (mFullScreenPortrait) return;
        if (mCurrentOrientation == LANDSCAPE) return;
        if (mCurrentOrientation == PORTRAIT
                && activity.getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
                && isFullScreen()) {
            mCurrentOrientation = LANDSCAPE;
            return;
        }
        mCurrentOrientation = LANDSCAPE;
        if (!isFullScreen()) {
            startFullScreen();
        }
        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    }

    /**
     * 反向横屏
     */
    protected void onOrientationReverseLandscape(Activity activity) {
        if (mFullScreenPortrait) return;
        if (mCurrentOrientation == REVERSE_LANDSCAPE) return;
        if (mCurrentOrientation == PORTRAIT
                && activity.getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
                && isFullScreen()) {
            mCurrentOrientation = REVERSE_LANDSCAPE;
            return;
        }
        mCurrentOrientation = REVERSE_LANDSCAPE;
        if (!isFullScreen()) {
            startFullScreen();
        }

        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
    }

    public BaseIjkVideoView(@NonNull Context context) {
        this(context, null);
    }


    public BaseIjkVideoView(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public BaseIjkVideoView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mPlayerConfig = new PlayerConfig.Builder().build();

        if (context instanceof AppCompatActivity) {
            mAttachActivity = (AppCompatActivity) context;
        } else {
            throw new IllegalArgumentException("Context must be AppCompatActivity");
        }
    }

    /**
     * 初始化播放器
     */
    protected void initPlayer() {
        if (mMediaPlayer == null) {
            if (mPlayerConfig.mAbstractPlayer != null) {
                mMediaPlayer = mPlayerConfig.mAbstractPlayer;
            } else {
                SDKLog.info(TAG, "initPlayer, new IjkPlayer");
                mMediaPlayer = new IjkPlayer(getContext());
            }
            mMediaPlayer.bindVideoView(this);
            mMediaPlayer.initPlayer();
            mMediaPlayer.setEnableMediaCodec(mPlayerConfig.enableMediaCodec);
            mMediaPlayer.setLooping(mPlayerConfig.isLooping);
        }
    }

    protected abstract void setPlayState(int playState);

    protected abstract void setPlayerState(int playerState);

    /**
     * 开始准备播放（直接播放）
     */
    protected void startPrepare(boolean needReset) {
        if (TextUtils.isEmpty(mCurrentUrl) && mAssetFileDescriptor == null) return;
        if (needReset) mMediaPlayer.reset();
        if (mAssetFileDescriptor != null) {
            mMediaPlayer.setDataSource(mAssetFileDescriptor);
        } else {
            mMediaPlayer.setDataSource(mCurrentUrl, mHeaders);
        }
        mMediaPlayer.prepareAsync();
        setPlayState(STATE_PREPARING);
        setPlayerState(isFullScreen() ? PLAYER_FULL_SCREEN : PLAYER_NORMAL);

//        if (mOnPlayListener != null) {
//            mOnPlayListener.play();
//        }
    }

    /**
     * 重试
     */
    @Override
    public void retry() {
        SDKLog.info(TAG, "retry, url=" + mCurrentUrl);
        if (mOnPlayListener != null) {
            mOnPlayListener.play();
        }
    }

    /**
     * 开始播放
     */
    @Override
    public void start() {
        SDKLog.info(TAG, "start, url=" + mCurrentUrl);
        if (mCurrentPlayState == STATE_IDLE) {
            startPlay();
        } else if (mCurrentPlayState == STATE_PLAYBACK_COMPLETED) {
            retry();
        } else if (isInPlaybackState()) {
            startInPlaybackState();
        }
        setKeepScreenOn(true);
        if (mAudioFocusHelper != null) {
            mAudioFocusHelper.requestFocus();
        }

        // 视频播放时开启屏幕常亮
//        mAttachActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        if (mOnPlayListener != null) {
            mOnPlayListener.play();
        }
    }

    /**
     * 第一次播放
     */
    protected void startPlay() {
        SDKLog.info(TAG, "startPlay, url=" + mCurrentUrl);
        if (!mPlayerConfig.disableAudioFocus) {
            mAudioManager = (AudioManager) getContext().getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
            mAudioFocusHelper = new AudioFocusHelper();
        }
        if (mPlayerConfig.savingProgress) {
            mCurrentPosition = ProgressUtil.getSavedProgress(mCurrentUrl);
        }
        if (mPlayerConfig.mAutoRotate)
            mOrientationEventListener.enable();
        initPlayer();
        startPrepare(false);
    }

    /**
     * 播放状态下开始播放
     */
    protected void startInPlaybackState() {
        SDKLog.info(TAG, "startInPlaybackState, url=" + mCurrentUrl);
        mMediaPlayer.start();
        setPlayState(STATE_PLAYING);
    }

    /**
     * 暂停播放
     */
    @Override
    public void pause() {
        SDKLog.info(TAG, "pause, url=" + mCurrentUrl);
        if (isPlaying()) {
            mMediaPlayer.pause();
            setPlayState(STATE_PAUSED);
            setKeepScreenOn(false);
            if (mAudioFocusHelper != null) {
                mAudioFocusHelper.abandonFocus();
            }
        }
        // 视频暂停时关闭屏幕常亮
//        mAttachActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        if (mOnPauseListener != null) {
            mOnPauseListener.pause();
        }

    }

    /**
     * 停止播放
     */
    @Override
    public void stop() {
        SDKLog.info(TAG, "stop, url=" + mCurrentUrl);
        if (isPlaying()) {
            mMediaPlayer.stop();
            onCompletion();
        }
        if (mOnStopListener != null) {
            mOnStopListener.stop();
        }
    }

    /**
     * 继续播放
     */
    public void resume() {
        SDKLog.info(TAG, "resume, url=" + mCurrentUrl);
        if (isInPlaybackState()
                && !mMediaPlayer.isPlaying()) {
            mMediaPlayer.start();
            setPlayState(STATE_PLAYING);
            if (mAudioFocusHelper != null)
                mAudioFocusHelper.requestFocus();
            setKeepScreenOn(true);
        }
    }

    /**
     * 停止播放
     */
    public void stopPlayback() {
        SDKLog.info(TAG, "stopPlayback, url=" + mCurrentUrl);
        if (mPlayerConfig.savingProgress && isInPlaybackState())
            ProgressUtil.saveProgress(mCurrentUrl, mCurrentPosition);
        if (mMediaPlayer != null) {
            mMediaPlayer.stop();
            setPlayState(STATE_IDLE);
            if (mAudioFocusHelper != null)
                mAudioFocusHelper.abandonFocus();
            setKeepScreenOn(false);
        }
        onPlayStopped();
    }

    /**
     * 释放播放器
     */
    public void release() {
        SDKLog.info(TAG, "release, url=" + mCurrentUrl);
        if (mPlayerConfig.savingProgress && isInPlaybackState())
            ProgressUtil.saveProgress(mCurrentUrl, mCurrentPosition);
        if (mMediaPlayer != null) {
            mMediaPlayer.release();
            mMediaPlayer = null;
            setPlayState(STATE_IDLE);
            if (mAudioFocusHelper != null)
                mAudioFocusHelper.abandonFocus();
            setKeepScreenOn(false);
        }
        onPlayStopped();
//        if (mVideoController != null) {
////            mVideoController = null;
//            mVideoController.setMediaPlayer(null);
//            mVideoController = null;
//        }

        // 关闭屏幕常亮
//        mAttachActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        if (isEnableRecordPlayerEvent()) {
            PlayerEventManager.getInstance(BaseIjkVideoView.this.mAttachActivity).uploadPlayerEventData();
        }


    }

    private void onPlayStopped() {
        if (mVideoController != null) mVideoController.hideStatusView();
        mOrientationEventListener.disable();
        mIsLockFullScreen = false;
        mCurrentPosition = 0;
    }

    /**
     * 监听播放状态变化
     */
    public void addOnVideoViewStateChangeListener(@NonNull OnVideoViewStateChangeListener listener) {
        if (mOnVideoViewStateChangeListeners == null) {
            mOnVideoViewStateChangeListeners = new ArrayList<>();
        }
        mOnVideoViewStateChangeListeners.add(listener);
    }

    /**
     * 移除播放状态监听
     */
    public void removeOnVideoViewStateChangeListener(@NonNull OnVideoViewStateChangeListener listener) {
        if (mOnVideoViewStateChangeListeners != null) {
            mOnVideoViewStateChangeListeners.remove(listener);
        }
    }

    /**
     * 移除所有播放状态监听
     */
    public void clearOnVideoViewStateChangeListeners() {
        if (mOnVideoViewStateChangeListeners != null) {
            mOnVideoViewStateChangeListeners.clear();
        }
    }

    /**
     * 是否处于播放状态
     */
    protected boolean isInPlaybackState() {
        return (mMediaPlayer != null
                && mCurrentPlayState != STATE_ERROR
                && mCurrentPlayState != STATE_IDLE
                && mCurrentPlayState != STATE_PREPARING
                && mCurrentPlayState != STATE_PLAYBACK_COMPLETED);
    }

    /**
     * 获取视频总时长
     */
    @Override
    public long getDuration() {
        if (isInPlaybackState()) {
            return mMediaPlayer.getDuration();
        }
        return 0;
    }

    /**
     * 获取当前播放的位置
     */
    @Override
    public long getCurrentPosition() {
        if (isInPlaybackState()) {
            mCurrentPosition = mMediaPlayer.getCurrentPosition();
            return mCurrentPosition;
        }
        return 0;
    }

    /**
     * 调整播放进度
     */
    @Override
    public void seekTo(long pos) {
        if (isInPlaybackState()) {
            mMediaPlayer.seekTo(pos);

            if (mOnSeekToListener != null) {
                mOnSeekToListener.seekTo(pos);
            }
        }
    }

    /**
     * 是否处于播放状态
     */
    @Override
    public boolean isPlaying() {
        return isInPlaybackState() && mMediaPlayer.isPlaying();
    }

    /**
     * 获取当前缓冲百分比
     */
    @Override
    public int getBufferedPercentage() {
        return mMediaPlayer != null ? mMediaPlayer.getBufferedPercentage() : 0;
    }

    /**
     * 设置静音
     */
    @Override
    public void setMute(boolean isMute) {
        SDKLog.info(TAG, "setMute, isMute=" + isMute);
        if (mMediaPlayer != null) {
            this.mIsMute = isMute;
            float volume = isMute ? 0.0f : 1.0f;
            mMediaPlayer.setVolume(volume, volume);
            if (isMute) {
                if (mOnMuteListener != null) {
                    mOnMuteListener.mute();
                }
            } else {
                if (mOnResumeVolumeListener != null) {
                    mOnResumeVolumeListener.resumeVolume();
                }
            }

        }
    }

    /**
     * 是否处于静音状态
     */
    @Override
    public boolean isMute() {
        return mIsMute;
    }

    /**
     * 设置controller是否处于锁定状态
     */
    @Override
    public void setLock(boolean isLocked) {
        this.mIsLockFullScreen = isLocked;
    }

    /**
     * 获取当前播放视频的标题
     */
    @Override
    public String getTitle() {
        return mCurrentTitle;
    }

    /**
     * 视频播放出错回调
     */
    @Override
    public void onError() {
        setPlayState(STATE_ERROR);
        if (mOnErrorListener != null) {
            mOnErrorListener.error();
        }
    }

    /**
     * 视频播放完成回调
     */
    @Override
    public void onCompletion() {
        setPlayState(STATE_PLAYBACK_COMPLETED);
        setKeepScreenOn(false);
        mCurrentPosition = 0;
//        if (mOnStopListener != null) {
//            mOnStopListener.stop();
//        }
    }

    @Override
    public void onInfo(int what, int extra) {
        switch (what) {
            case IMediaPlayer.MEDIA_INFO_BUFFERING_START:
                setPlayState(STATE_BUFFERING);
                break;
            case IMediaPlayer.MEDIA_INFO_BUFFERING_END:
                setPlayState(STATE_BUFFERED);
                break;
            case IjkMediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START: // 视频开始渲染
                setPlayState(STATE_PLAYING);
                if (getWindowVisibility() != VISIBLE) pause();
                break;
        }
    }

    /**
     * 视频缓冲完毕，准备开始播放时回调
     */
    @Override
    public void onPrepared() {
        setPlayState(STATE_PREPARED);
        if (mCurrentPosition > 0) {
            seekTo(mCurrentPosition);
        }
    }

    public void setPlayerConfig(PlayerConfig config) {
        this.mPlayerConfig = config;
    }

    /**
     * 获取当前播放器的状态
     */
    public int getCurrentPlayerState() {
        return mCurrentPlayerState;
    }

    /**
     * 获取当前的播放状态
     */
    public int getCurrentPlayState() {
        return mCurrentPlayState;
    }


    /**
     * 获取缓冲速度
     */
    @Override
    public long getTcpSpeed() {
        return mMediaPlayer.getTcpSpeed();
    }

    /**
     * 设置播放速度
     */
    @Override
    public void setSpeed(float speed) {
        if (isInPlaybackState()) {
            mMediaPlayer.setSpeed(speed);
        }
    }

    @Override
    public float getSpeed() {
        return mMediaPlayer.getSpeed();
    }

    /**
     * 重新播放
     */
    @Override
    public void refresh() {
        mCurrentPosition = 0;
        retry();
    }

    /**
     * 设置视频地址
     */
    public void setUrl(String url) {
        this.mCurrentUrl = url;
    }

    /**
     * 设置包含请求头信息的视频地址
     *
     * @param url     视频地址
     * @param headers 请求头
     */
    public void setUrl(String url, Map<String, String> headers) {
        mCurrentUrl = url;
        mHeaders = headers;
    }

    public String getCurrentUrl() {
        return mCurrentUrl;
    }

    /**
     * 用于播放assets里面的视频文件
     */
    public void setAssetFileDescriptor(AssetFileDescriptor fd) {
        this.mAssetFileDescriptor = fd;
    }

    /**
     * 一开始播放就seek到预先设置好的位置
     */
    public void skipPositionWhenPlay(int position) {
        this.mCurrentPosition = position;
    }

    /**
     * 设置标题
     */
    public void setTitle(String title) {
        if (title != null) {
            this.mCurrentTitle = title;
        }
    }

    /**
     * 设置音量 0.0f-1.0f 之间
     *
     * @param v1 左声道音量
     * @param v2 右声道音量
     */
    public void setVolume(float v1, float v2) {
        if (mMediaPlayer != null) {
            mMediaPlayer.setVolume(v1, v2);
        }
    }

    /**
     * 音频焦点改变监听
     */
    private class AudioFocusHelper implements AudioManager.OnAudioFocusChangeListener {
        private boolean startRequested = false;
        private boolean pausedForLoss = false;
        private int currentFocus = 0;

        @Override
        public void onAudioFocusChange(int focusChange) {
            if (currentFocus == focusChange) {
                return;
            }

            currentFocus = focusChange;
            switch (focusChange) {
                case AudioManager.AUDIOFOCUS_GAIN://获得焦点
                case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT://暂时获得焦点
                    if (startRequested || pausedForLoss) {
                        start();
                        startRequested = false;
                        pausedForLoss = false;
                    }
                    if (mMediaPlayer != null && !mIsMute)//恢复音量
                        mMediaPlayer.setVolume(1.0f, 1.0f);
                    break;
                case AudioManager.AUDIOFOCUS_LOSS://焦点丢失
                case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT://焦点暂时丢失
                    if (isPlaying()) {
                        pausedForLoss = true;
                        pause();
                    }
                    break;
                case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK://此时需降低音量
                    if (mMediaPlayer != null && isPlaying() && !mIsMute) {
                        mMediaPlayer.setVolume(0.1f, 0.1f);
                    }
                    break;
            }
        }

        /**
         * Requests to obtain the audio focus
         *
         * @return True if the focus was granted
         */
        boolean requestFocus() {
            if (currentFocus == AudioManager.AUDIOFOCUS_GAIN) {
                return true;
            }

            if (mAudioManager == null) {
                return false;
            }

            int status = mAudioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
            if (AudioManager.AUDIOFOCUS_REQUEST_GRANTED == status) {
                currentFocus = AudioManager.AUDIOFOCUS_GAIN;
                return true;
            }

            startRequested = true;
            return false;
        }

        /**
         * Requests the system to drop the audio focus
         *
         * @return True if the focus was lost
         */
        boolean abandonFocus() {

            if (mAudioManager == null) {
                return false;
            }

            startRequested = false;
            int status = mAudioManager.abandonAudioFocus(this);
            return AudioManager.AUDIOFOCUS_REQUEST_GRANTED == status;
        }
    }

    @Override
    public void setPauseAd(String url) {
        this.mPauseAdUrl = url;
    }

    @Override
    public void setThumbUrl(String thumbUrl) {
        this.mThumbUrl = thumbUrl;
    }

    @Override
    public String getThumbUrl() {
        return mThumbUrl;
    }

    @Override
    public String getPauseAdUrl() {
        return mPauseAdUrl;
    }

    @Override
    public long getPlayableVideoDuration() {
        return mPlayableVideoDuration;
    }

    @Override
    public void setPlayableVideoDuration(long sec) {
        mPlayableVideoDuration = sec;
    }

    @Override
    public void doStartStopFullScreen() {
        mVideoController.doStartStopFullScreen();
    }

    public boolean isEnableRecordPlayerEvent() {
        return mEnableRecordPlayerEvent;
    }

    public void setEnableRecordPlayerEvent(boolean enableRecordPlayerEvent) {
        this.mEnableRecordPlayerEvent = enableRecordPlayerEvent;
    }

    public List<VideoModel> getVideos() {
        return mVideos;
    }

    public void setVideos(List<VideoModel> mVideoModels) {
        this.mVideos = mVideoModels;
    }

    public WaterMarkTextDetail getWatermark() {
        return mWatermark;
    }

    public void setWatermark(WaterMarkTextDetail watermark) {
        this.mWatermark = watermark;
    }

    public MarqueeTextDetail getMarqueeText() {
        return mMarqueeText;
    }

    public void setMarqueeText(MarqueeTextDetail marqueeText) {
        if (mVideoController != null) {
            this.mMarqueeText = marqueeText;
            ((StandardVideoController) mVideoController).showMarquee(marqueeText);
        }
    }

    public void setFullScreenPortrait(boolean enable) {
        mFullScreenPortrait = enable;
    }

    public boolean isFullScreenPortrait() {
        return mFullScreenPortrait;
    }

    public AppCompatActivity getAttachActivity() {
        return mAttachActivity;
    }

    protected void load() { }

    //---------------播放器事件接口------------------------------

    protected OnPlayListener mOnPlayListener;
    protected OnLoadStartListener mOnLoadStartListener;
    protected OnPauseListener mOnPauseListener;
    protected OnStopListener mOnStopListener;
    protected OnErrorListener mOnErrorListener;
    protected OnEnterFullScreenListener mOnEnterFullScreenListener;
    protected OnExitFullScreenListener mOnExitFullScreenListener;
    protected OnMuteListener mOnMuteListener;
    protected OnResumeVolumeListener mOnResumeVolumeListener;
    protected OnSetVolumeListener mOnSetVolumeListener;
    protected OnSeekToListener mOnSeekToListener;
    protected OnPauseAdClickListener mOnPauseAdClickListener;
    protected OnProgressChangeListener mOnProgressChangeListener;
    protected MarqueeViewListener mMarqueeViewListener;

    public OnPlayListener getOnPlayListener() {
        return mOnPlayListener;
    }

    public void setOnPlayListener(OnPlayListener onPlayListener) {
        this.mOnPlayListener = onPlayListener;
    }

    public OnLoadStartListener getOnLoadStartListener() {
        return mOnLoadStartListener;
    }

    public void setOnLoadStartListener(OnLoadStartListener onLoadStartListener) {
        this.mOnLoadStartListener = onLoadStartListener;
    }

    public OnPauseListener getOnPauseListener() {
        return mOnPauseListener;
    }

    public void setOnPauseListener(OnPauseListener onPauseListener) {
        this.mOnPauseListener = onPauseListener;
    }

    public OnStopListener getOnStopListener() {
        return mOnStopListener;
    }

    public void setOnStopListener(OnStopListener onStopListener) {
        this.mOnStopListener = onStopListener;
    }

    public OnErrorListener getOnErrorListener() {
        return mOnErrorListener;
    }

    public void setOnErrorListener(OnErrorListener onErrorListener) {
        this.mOnErrorListener = onErrorListener;
    }

    public OnEnterFullScreenListener getOnEnterFullScreenListener() {
        return mOnEnterFullScreenListener;
    }

    public void setOnEnterFullScreenListener(OnEnterFullScreenListener onEnterFullScreenListener) {
        this.mOnEnterFullScreenListener = onEnterFullScreenListener;
    }

    public OnExitFullScreenListener getOnExitFullScreenListener() {
        return mOnExitFullScreenListener;
    }

    public void setOnExitFullScreenListener(OnExitFullScreenListener onExitFullScreenListener) {
        this.mOnExitFullScreenListener = onExitFullScreenListener;
    }

    public OnMuteListener getOnMuteListener() {
        return mOnMuteListener;
    }

    public void setOnMuteListener(OnMuteListener onMuteListener) {
        this.mOnMuteListener = onMuteListener;
    }

    public OnResumeVolumeListener getOnResumeVolumeListener() {
        return mOnResumeVolumeListener;
    }

    public void setOnResumeVolumeListener(OnResumeVolumeListener onResumeVolumeListener) {
        this.mOnResumeVolumeListener = onResumeVolumeListener;
    }

    public OnSetVolumeListener getOnSetVolumeListener() {
        return mOnSetVolumeListener;
    }

    public void setOnSetVolumeListener(OnSetVolumeListener onSetVolumeListener) {
        this.mOnSetVolumeListener = onSetVolumeListener;
    }

    public OnSeekToListener getOnSeekToListener() {
        return mOnSeekToListener;
    }

    public void setOnSeekToListener(OnSeekToListener onSeekToListener) {
        this.mOnSeekToListener = onSeekToListener;
    }

    public OnPauseAdClickListener getOnPauseAdClickListener() {
        return mOnPauseAdClickListener;
    }

    public void setOnPauseAdClickListener(OnPauseAdClickListener onPauseAdClickListener) {
        this.mOnPauseAdClickListener = onPauseAdClickListener;
    }

    public OnProgressChangeListener getOnProgressChangeListener() {
        return mOnProgressChangeListener;
    }

    public void setOnProgressChangeListener(OnProgressChangeListener onProgressChangeListener) {
        this.mOnProgressChangeListener = onProgressChangeListener;
    }

    public MarqueeViewListener getMarqueeViewListener() {
        return mMarqueeViewListener;
    }

    public void setMarqueeViewListener(MarqueeViewListener marqueeViewListener) {
        this.mMarqueeViewListener = marqueeViewListener;
    }

    public Configurator fromSource(List<VideoModel> videos) {
        return new Configurator(videos);
    }


    public class Configurator {
        private List<VideoModel> videos;
        private String pauseAdUrl;
        private String thumbUrl;
        private boolean enableRecordPlayerEvent = true; // 默认上传
        private WaterMarkTextDetail watermark;
        private long playableVideoDuration;
        private OnPlayListener onPlayListener;
        private OnLoadStartListener onLoadStartListener;
        private OnPauseListener onPauseListener;
        private OnStopListener onStopListener;
        private OnErrorListener onErrorListener;
        private OnEnterFullScreenListener onEnterFullScreenListener;
        private OnExitFullScreenListener onExitFullScreenListener;
        private OnMuteListener onMuteListener;
        private OnResumeVolumeListener onResumeVolumeListener;
        private OnSetVolumeListener onSetVolumeListener;
        private OnSeekToListener onSeekToListener;
        private OnPauseAdClickListener onPauseAdClickListener;
        private OnProgressChangeListener onProgressChangeListener;
        private MarqueeViewListener marqueeViewListener;

        private Configurator(List<VideoModel> videos) {
            this.videos = videos;
        }

        public Configurator playableVideoDuration(long playableVideoDuration) {
            this.playableVideoDuration = playableVideoDuration;
            return this;
        }

        public Configurator pauseAdUrl(String pauseAdUrl) {
            this.pauseAdUrl = pauseAdUrl;
            return this;
        }

        public Configurator pauseAd(String pauseAdUrl, OnPauseAdClickListener onPauseAdClickListener) {
            this.pauseAdUrl = pauseAdUrl;
            this.onPauseAdClickListener = onPauseAdClickListener;
            return this;
        }

        public Configurator thumbUrl(String thumbUrl) {
            this.thumbUrl = thumbUrl;
            return this;
        }

        public Configurator enableRecordPlayerEvent(boolean enable) {
            this.enableRecordPlayerEvent = enable;
            return this;
        }

        public Configurator watermark(String text, String position, String color, int size) {
            this.watermark = new WaterMarkTextDetail();
            this.watermark.setText(text);
            this.watermark.setPosition(position);
            this.watermark.setColor(Color.parseColor(color));
            this.watermark.setFontSize(size);
            return this;
        }

        public Configurator onPlay(OnPlayListener onPlayListener) {
            this.onPlayListener = onPlayListener;
            return this;
        }

        public Configurator onLoadStart(OnLoadStartListener onLoadStartListener) {
            this.onLoadStartListener = onLoadStartListener;
            return this;
        }

        public Configurator onPause(final OnPauseListener onPauseListener) {
            this.onPauseListener = onPauseListener;
            return this;
        }

        public Configurator onStop(OnStopListener onStopListener) {
            this.onStopListener = onStopListener;
            return this;
        }

        public Configurator onError(OnErrorListener onErrorListener) {
            this.onErrorListener = onErrorListener;
            return this;
        }

        public Configurator onEnterFullScreen(OnEnterFullScreenListener onEnterFullScreenListener) {
            this.onEnterFullScreenListener = onEnterFullScreenListener;
            return this;
        }

        public Configurator onExitFullScreen(OnExitFullScreenListener onExitFullScreenListener) {
            this.onExitFullScreenListener = onExitFullScreenListener;
            return this;
        }

        public Configurator onMute(OnMuteListener onMuteListener) {
            this.onMuteListener = onMuteListener;
            return this;
        }

        public Configurator onResumeVolume(OnResumeVolumeListener onResumeVolumeListener) {
            this.onResumeVolumeListener = onResumeVolumeListener;
            return this;
        }

        public Configurator onSetVolume(OnSetVolumeListener onSetVolumeListener) {
            this.onSetVolumeListener = onSetVolumeListener;
            return this;
        }

        public Configurator onSeekTo(OnSeekToListener onSeekToListener) {
            this.onSeekToListener = onSeekToListener;
            return this;
        }

        public Configurator onProgressChange(OnProgressChangeListener onProgressChangeListener) {
            this.onProgressChangeListener = onProgressChangeListener;
            return this;
        }

        public Configurator onMarqueeView(MarqueeViewListener marqueeViewListener) {
            this.marqueeViewListener = marqueeViewListener;
            return this;
        }

        public void load() {
            BaseIjkVideoView.this.setVideos(videos);
            BaseIjkVideoView.this.setPlayableVideoDuration(playableVideoDuration);
            BaseIjkVideoView.this.setPauseAd(pauseAdUrl);
            BaseIjkVideoView.this.setThumbUrl(thumbUrl);
            BaseIjkVideoView.this.setWatermark(watermark);

            BaseIjkVideoView.this.setEnableRecordPlayerEvent(enableRecordPlayerEvent);
            BaseIjkVideoView.this.setOnLoadStartListener(onLoadStartListener);
            BaseIjkVideoView.this.setOnSetVolumeListener(onSetVolumeListener);
            BaseIjkVideoView.this.setOnProgressChangeListener(onProgressChangeListener);
            BaseIjkVideoView.this.setMarqueeViewListener(marqueeViewListener);

            BaseIjkVideoView.this.setOnPlayListener(new OnPlayListener() {
                @Override
                public void play() {
                    PlayerEventManager.getInstance(BaseIjkVideoView.this.mAttachActivity).savePlayerEvent(PlayerConstants.PlayerEvent.PLAY, BaseIjkVideoView.this);
                    if (onPlayListener != null) {
                        onPlayListener.play();
                    }
                }
            });

            BaseIjkVideoView.this.setOnPauseListener(new OnPauseListener() {
                @Override
                public void pause() {
                    PlayerEventManager.getInstance(BaseIjkVideoView.this.mAttachActivity).savePlayerEvent(PlayerConstants.PlayerEvent.PAUSE, BaseIjkVideoView.this);
                    if (onPauseListener != null) {
                        onPauseListener.pause();
                    }
                }
            });

            BaseIjkVideoView.this.setOnStopListener(new OnStopListener() {
                @Override
                public void stop() {
                    PlayerEventManager.getInstance(BaseIjkVideoView.this.mAttachActivity).savePlayerEvent(PlayerConstants.PlayerEvent.STOP, BaseIjkVideoView.this);
                    if (onStopListener != null) {
                        onStopListener.stop();
                    }
                }
            });

            BaseIjkVideoView.this.setOnErrorListener(new OnErrorListener() {
                @Override
                public void error() {
                    PlayerEventManager.getInstance(BaseIjkVideoView.this.mAttachActivity).savePlayerEvent(PlayerConstants.PlayerEvent.ERROR, BaseIjkVideoView.this);
                    if (onErrorListener != null) {
                        onErrorListener.error();
                    }
                }
            });

            BaseIjkVideoView.this.setOnEnterFullScreenListener(new OnEnterFullScreenListener() {
                @Override
                public void enterFullScreen() {
                    PlayerEventManager.getInstance(BaseIjkVideoView.this.mAttachActivity).savePlayerEvent(PlayerConstants.PlayerEvent.FULLSCREEN, BaseIjkVideoView.this);
                    if (onEnterFullScreenListener != null) {
                        onEnterFullScreenListener.enterFullScreen();
                    }
                }
            });

            BaseIjkVideoView.this.setOnExitFullScreenListener(new OnExitFullScreenListener() {
                @Override
                public void exitFullScreen() {
                    PlayerEventManager.getInstance(BaseIjkVideoView.this.mAttachActivity).savePlayerEvent(PlayerConstants.PlayerEvent.EXIT_FULLSCREEN, BaseIjkVideoView.this);
                    if (onExitFullScreenListener != null) {
                        onExitFullScreenListener.exitFullScreen();
                    }
                }
            });

            BaseIjkVideoView.this.setOnMuteListener(new OnMuteListener() {
                @Override
                public void mute() {
                    PlayerEventManager.getInstance(BaseIjkVideoView.this.mAttachActivity).savePlayerEvent(PlayerConstants.PlayerEvent.MUTE, BaseIjkVideoView.this);
                    if (onMuteListener != null) {
                        onMuteListener.mute();
                    }
                }
            });

            BaseIjkVideoView.this.setOnResumeVolumeListener(new OnResumeVolumeListener() {
                @Override
                public void resumeVolume() {
                    PlayerEventManager.getInstance(BaseIjkVideoView.this.mAttachActivity).savePlayerEvent(PlayerConstants.PlayerEvent.RESUME_VOLUM, BaseIjkVideoView.this);
                    if (onResumeVolumeListener != null) {
                        onResumeVolumeListener.resumeVolume();
                    }
                }
            });

            BaseIjkVideoView.this.setOnSeekToListener(new OnSeekToListener() {
                @Override
                public void seekTo(long pos) {
                    PlayerEventManager.getInstance(BaseIjkVideoView.this.mAttachActivity).savePlayerEvent(PlayerConstants.PlayerEvent.SEEK, BaseIjkVideoView.this);
                    if (onSeekToListener != null) {
                        onSeekToListener.seekTo(pos);
                    }
                }
            });

            BaseIjkVideoView.this.setOnPauseAdClickListener(new OnPauseAdClickListener() {
                @Override
                public void click() {
                    if (onPauseAdClickListener != null) {
                        onPauseAdClickListener.click();
                    }
                }
            });

            BaseIjkVideoView.this.load();
        }
    }

}
